﻿' ******************************************************************************
' ** 
' **  Yahoo Finance Managed
' **  Written by Marius Häusler 2010
' **  It would be pleasant, if you contact me when you are using this code.
' **  Contact: YahooFinanceManaged@gmail.com
' **  Project Home: http://code.google.com/p/yahoo-finance-managed/
' **  
' ******************************************************************************
' **  
' **  Copyright 2010 Marius Häusler
' **  
' **  Licensed under the Apache License, Version 2.0 (the "License");
' **  you may not use this file except in compliance with the License.
' **  You may obtain a copy of the License at
' **  
' **    http://www.apache.org/licenses/LICENSE-2.0
' **  
' **  Unless required by applicable law or agreed to in writing, software
' **  distributed under the License is distributed on an "AS IS" BASIS,
' **  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' **  See the License for the specific language governing permissions and
' **  limitations under the License.
' ** 
' ******************************************************************************


Namespace RSS

    ''' <summary>
    ''' Class for downloading RSS feeds
    ''' </summary>
    ''' <remarks></remarks>
    Public Class FeedDownload
        Inherits Base.Download
        Public Event AsyncDownloadCompleted(ByVal sender As Base.Download, ByVal ea As FeedDownloadCompletedEventArgs)

        Private mXmlParser As New ImportExport.XML

        Public Overloads Function Download(ByVal url As String) As FeedResponse
            If url = String.Empty Then Throw New ArgumentNullException("url", "The url is empty.")
            Return Me.Download(New Uri(url))
        End Function
        Public Overloads Function Download(ByVal url As Uri) As FeedResponse
            If url Is Nothing Then Throw New ArgumentNullException("url", "The url is null.")
            Return Me.ToResponse(MyBase.Download(url.ToString))
        End Function

        Public Overloads Sub DownloadAsync(ByVal url As String, Optional ByVal userArgs As Object = Nothing)
            If url = String.Empty Then Throw New ArgumentNullException("url", "The url is empty.")
            Me.DownloadAsync(New Uri(url), userArgs)
        End Sub
        Public Overloads Sub DownloadAsync(ByVal url As Uri, Optional ByVal userArgs As Object = Nothing)
            If url Is Nothing Then Throw New ArgumentNullException("url", "The url is null.")
            MyBase.DownloadAsync(url.ToString, New AsyncDownloadArgs(userArgs) With {.URL = url})
        End Sub

        ''' <summary>
        ''' Default constructor
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
        End Sub

        Private Sub DownloadAsync_Completed(ByVal sender As Base.Download, ByVal ba As Base.StreamDownloadCompletedEventArgs) Handles MyBase.AsyncStreamDownloadCompleted
            Dim dlArgs As AsyncDownloadArgs = DirectCast(ba.UserArgs, AsyncDownloadArgs)
            Dim args As New FeedDownloadCompletedEventArgs(dlArgs.UserArgs, Me.ToResponse(ba.Response), dlArgs.URL)
            RaiseEvent AsyncDownloadCompleted(Me, args)
        End Sub

        Private Function ToResponse(ByVal resp As Base.StreamResponse) As FeedResponse
            Dim feeds As New List(Of Feed)
            Dim enc As System.Text.Encoding = Nothing
            Try
                Dim doc As New XmlDocument
                doc.Load(resp.Result)
                If doc.FirstChild IsNot Nothing AndAlso TypeOf doc.FirstChild Is XmlDeclaration Then
                    Try
                        enc = System.Text.Encoding.GetEncoding(DirectCast(doc.FirstChild, XmlDeclaration).Encoding)
                    Catch ex As Exception
                    End Try
                End If
                For Each f As XmlNode In doc.GetElementsByTagName("channel")
                    feeds.Add(mXmlParser.ToFeed(f))
                Next
            Catch ex As Exception
            Finally
                mHelper.CloseStream(resp.Result)
            End Try
            Return New FeedResponse(resp.Connection, feeds.ToArray, enc)
        End Function

        Private Class AsyncDownloadArgs
            Inherits Base.DownloadEventArgs
            Public URL As Uri
            Public Sub New(ByVal userArgs As Object)
                MyBase.New(userArgs)
            End Sub
        End Class

    End Class

    Public Class FeedDownloadCompletedEventArgs
        Inherits Base.DownloadCompletedEventArgs

        Private mURL As Uri

        Public ReadOnly Property URL() As Uri
            Get
                Return mURL
            End Get
        End Property
        Public Overloads ReadOnly Property Response() As FeedResponse
            Get
                Return DirectCast(MyBase.Response, FeedResponse)
            End Get
        End Property

        Friend Sub New(ByVal userArgs As Object, ByVal resp As FeedResponse, ByVal url As Uri)
            MyBase.New(userArgs, resp)
            mURL = url
        End Sub

    End Class

    Public Class FeedResponse
        Inherits Base.Response

        Private mEncoding As System.Text.Encoding = Nothing

        Public ReadOnly Property Encoding() As System.Text.Encoding
            Get
                Return mEncoding
            End Get
        End Property
        Public Overloads ReadOnly Property Result() As Feed()
            Get
                Return TryCast(MyBase.Result, Feed())
            End Get
        End Property

        Friend Sub New(ByVal info As Base.ConnectionInfo, ByVal result() As Feed, ByVal enc As System.Text.Encoding)
            MyBase.New(info, result)
            mEncoding = enc
        End Sub

    End Class

End Namespace